package controller;

import gui.browse.BrowseListener;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;

import model.Endereco;
import model.Status;
import model.Usuario;
import dao.UsuarioDAO;

public class UsuarioController implements ControllerBrowse {

	private UsuarioDAO usuarioDAO;
	private static UsuarioController instance;

	private UsuarioController() {
	}

	public static UsuarioController getInstance() {
		if (instance == null) {
			instance = new UsuarioController();
		}
		return instance;
	}

	public boolean inserirUsuario(String cpf, String nome, String email, String senha, 
			String profissao, String dataNascimento, Status status,
			String nomeDependente, String emailDependente, String logradouro, String numero, 
			String cidade, String cep) throws Exception {
		
		Endereco endereco = new Endereco(logradouro, numero, cidade, cep);
		Usuario usuario = new Usuario(0, cpf, nome, email, senha, profissao, dataNascimento, endereco, 
				status, nomeDependente, emailDependente);
		validaUsuario(usuario);
		return getUsuarioDAO().inserir(usuario);
	}

	public boolean alterarUsuario(int id, String cpf, String nome, String email, String senha, 
			String profissao, String dataNascimento, Status status,
			String nomeDependente, String emailDependente, String logradouro, String numero, 
			String cidade, String cep) throws Exception {
		
		Usuario usuario = buscarUsuarioPorId(id);
		
		usuario.setCpf(cpf);
		usuario.setNome(nome);
		usuario.setEmail(email);
		usuario.setSenha(senha);
		usuario.setProfissao(profissao);
		usuario.setDataNascimento(dataNascimento);
		usuario.setNomeDependente(nomeDependente);
		usuario.setEmailDependente(emailDependente);
		//Endere�o
		usuario.getEndereco().setLogradouro(logradouro);
		usuario.getEndereco().setNumero(numero);
		usuario.getEndereco().setCidade(cidade);
		usuario.getEndereco().setCep(cep);
		
		if (!usuario.getStatus().equals(status)){
			usuario.setStatus(status);
			if (status == Status.LIVRE){
				usuario.setDataStatus(null);
			} else {
				usuario.setDataStatus(new Date());	
			}
		}
		validaUsuario(usuario);
		return getUsuarioDAO().alterar(usuario);
	}

	public boolean excluirUsuario(int id) throws Exception {
		Usuario usuario = buscarUsuarioPorId(id);
		return getUsuarioDAO().delete(usuario);
	}

	public void verificaDesbloqueioDeUsuarios() {
		Collection<Usuario> usuariosBloqueados = new ArrayList<Usuario>();
		try {
			usuariosBloqueados = getUsuarioDAO().buscarUsuarioBloqueadoPorNome("");
		} catch (SQLException e) {
			e.printStackTrace();
		}

		if (usuariosBloqueados != null && !usuariosBloqueados.isEmpty()) {
			Date dataAtual = new Date();
			for (Usuario usuario : usuariosBloqueados) {
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(usuario.getDataStatus());

				if (usuario.getStatus().equals(Status.ADVERTENCIA)) {
					calendar.add(Calendar.DATE, 30);
				} else if (usuario.getStatus().equals(Status.SUSPENSAO)) {
					calendar.add(Calendar.DATE, 90);
				}

				if (calendar.getTime().compareTo(dataAtual) <= 0) {
					usuario.setStatus(Status.LIVRE);
					usuario.setDataStatus(null);
					getUsuarioDAO().alterar(usuario);
				}
			}
		} else {
			return;
		}
	}

	public Collection<Usuario> buscarUsuariosPorNome(String nome) throws Exception {
		return getUsuarioDAO().buscarUsuariosPorNome(nome);
	}

	public Usuario buscarUsuarioPorId(int id) throws Exception {
		return getUsuarioDAO().buscarUsuarioPorId(id);
	}

	public Usuario buscarUsuarioPorEmail(String email) throws Exception {
		return getUsuarioDAO().buscarUsuarioPorEmail(email);
	}

	public Collection<Usuario> buscarUsuarioBloqueadoPorNome(String nome) throws Exception {
		return getUsuarioDAO().buscarUsuarioBloqueadoPorNome(nome);
	}

	public Usuario verificaUsuarioSenha(String email, String senha) throws Exception {
		return getUsuarioDAO().verificaUsuarioSenha(email, senha);
	}

	public boolean verificaSeUsuarioPodeAcessar(String email) throws Exception {
		return getUsuarioDAO().verificaSeUsuarioPodeAcessar(email);
	}

	public void validaUsuario(Usuario usuario) throws Exception {
		if (usuario.getCpf() == null || usuario.getCpf().isEmpty()) {
			throw new Exception("CPF do usuario n�o informado!");
		}
		if (usuario.getNome() == null || usuario.getNome().isEmpty()) {
			throw new Exception("Nome n�o informado!");
		}
		if (usuario.getDataNascimento() == null || usuario.getDataNascimento().isEmpty()) {
			throw new Exception("Data de nascimento n�o informado!");
		}
		if (usuario.getEmail() == null || usuario.getEmail().isEmpty()) {
			throw new Exception("E-mail n�o informado!");
		}

		if (usuario.getEndereco().getLogradouro() == null || usuario.getEndereco().getLogradouro().isEmpty()) {
			throw new Exception("Rua n�o informada!");
		}
		if (usuario.getEndereco().getNumero() == null || usuario.getEndereco().getNumero().isEmpty()) {
			throw new Exception("N�mero n�o informado!");
		}
		if (usuario.getEndereco().getCep() == null || usuario.getEndereco().getCep().isEmpty()) {
			throw new Exception("Cep n�o informado!");
		}
		if (usuario.getEndereco().getCidade() == null || usuario.getEndereco().getCidade().isEmpty()) {
			throw new Exception("Cidade n�o informada!");
		}
		if (usuario.getProfissao() == null || usuario.getProfissao().isEmpty()) {
			throw new Exception("Profiss�o n�o informada!");
		}
		if (usuario.getSenha() == null || usuario.getSenha().isEmpty()) {
			throw new Exception("Senha n�o informada!");
		}

		if (usuario.getStatus().equals(Status.ADVERTENCIA)
				|| usuario.getStatus().equals(Status.EXPULSAO)
				|| usuario.getStatus().equals(Status.SUSPENSAO)) {
			usuario.setDataStatus(new Date());
		}
	}

	public UsuarioDAO getUsuarioDAO() {
		if (usuarioDAO == null) {
			usuarioDAO = new UsuarioDAO();
		}
		return usuarioDAO;
	}
	public Collection<Usuario> buscarUsuariosBloqueados() throws SQLException {
		return getUsuarioDAO().buscarUsuariosBloqueados();
	}

	@Override
	public ArrayList<HashMap<String, Object>> buscarDados() throws SQLException {
		return (ArrayList<HashMap<String, Object>>) getUsuarioDAO().buscarDadosUsuarioBrowse();
	}

}